﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Procedures.cs" company="">
//   
// </copyright>
// <summary>
//   The procedures.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace RescueRaiders.Models
{
    using System;
    using System.Linq;

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;

    /// <summary>
    /// The procedures.
    /// </summary>
    internal static class Procedures
    {
        /// <summary>
        /// The intersect pixels.
        /// </summary>
        /// <param name="transformA">
        /// The transform a.
        /// </param>
        /// <param name="widthA">
        /// The width a.
        /// </param>
        /// <param name="heightA">
        /// The height a.
        /// </param>
        /// <param name="dataA">
        /// The data a.
        /// </param>
        /// <param name="transformB">
        /// The transform b.
        /// </param>
        /// <param name="widthB">
        /// The width b.
        /// </param>
        /// <param name="heightB">
        /// The height b.
        /// </param>
        /// <param name="dataB">
        /// The data b.
        /// </param>
        /// <returns>
        /// The intersect pixels.
        /// </returns>
        public static Vector2 IntersectPixels(
            Matrix transformA,
            int widthA,
            int heightA,
            Color[] dataA,
            Matrix transformB,
            int widthB,
            int heightB,
            Color[] dataB)
        {
            // Calculate a matrix which transforms from A's local space into
            // world space and then into B's local space
            var transformAtoB = transformA * Matrix.Invert(transformB);

            // For each row of pixels in A
            foreach (var yA in Enumerable.Range(0, heightA))
            {
                // For each pixel in this row
                foreach (var xA in Enumerable.Range(0, widthA))
                {
                    // Calculate this pixel's location in B
                    var positionInA = new Vector2(xA, yA);
                    var positionInB = Vector2.Transform(positionInA, transformAtoB);

                    // Round to the nearest pixel
                    var xB = (int)Math.Round(positionInB.X);
                    var yB = (int)Math.Round(positionInB.Y);

                    // If the pixel lies within the bounds of B
                    if (0 > xB || xB >= widthB || 0 > yB || yB >= heightB)
                    {
                        continue;
                    }

                    // Get the colors of the overlapping pixels
                    var colorA = dataA[xA + yA * widthA];
                    var colorB = dataB[xB + yB * widthB];

                    // If both pixels are not completely transparent,
                    if (colorA.A != 0 && colorB.A != 0)
                    {
                        // then an intersection has been found
                        return Vector2.Transform(positionInA, transformA);
                    }
                }
            }

            // No intersection found
            return Vector2.Zero;
        }

        /// <summary>
        /// The transform.
        /// </summary>
        /// <param name="center">
        /// vector2 the origin in the world
        /// </param>
        /// <param name="rotation">
        /// Rotation
        /// </param>
        /// <param name="position">
        /// Position in considering to the center
        /// </param>
        /// <returns>
        /// </returns>
        public static Matrix Transform(Vector2 center, float rotation, Vector2 position)
        {
            var transform = Matrix.CreateTranslation(new Vector3(-center, 0.0f)) * Matrix.CreateRotationZ(rotation) *
                            Matrix.CreateTranslation(new Vector3(position, 0.0f));
            return transform;
        }
    }
}